﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;

namespace OpenLS.Spreadsheet.Formats.Biff.Records
{
    internal class CFMultistate : CFBase
    {
        private ushort unused;
        private byte reserved1;
        private IconSetType iIconSet;
        private bool fIconOnly;
        private bool reserved2;
        private bool fReverse;
        private readonly List<CFMStateItem> rgStates = new List<CFMStateItem>();

        public CFMultistate(IconSet iconSet)
        {
            iIconSet= iconSet.Type;
            fReverse = iconSet.Reverse;
            fIconOnly = !iconSet.ValueVisible;
            foreach (var item in iconSet.Objects)
                rgStates.Add(new CFMStateItem(item));
        }

        public CFMultistate()
        {
        }

        public IconSet ToIconSet(BiffReaderWorksheetContext context)
        {
            IconSet result = new IconSet();
            result.Type = this.iIconSet;
            result.Reverse = fReverse;
            result.ValueVisible = !fIconOnly;
            foreach (var item in this.rgStates)
                result.Objects.Add(item.ToObject(context));
            return result;
        }

        public override void Read(BinaryReader reader)
        {
            this.unused = reader.ReadUInt16();
            this.reserved1 = reader.ReadByte();
            var cStates = reader.ReadByte();
            this.iIconSet = (IconSetType) reader.ReadByte();
            var abc = reader.ReadByte();
            this.fIconOnly = (abc & 0x01) != 0;
            this.reserved2 = (abc & 0x02) != 0;
            this.fReverse = (abc & 0x04) != 0;
            Contract.Assert(this.Abc == abc);
            this.rgStates.Clear();
            for (int i = 0; i < cStates; i++)
            {
                CFMStateItem item = new CFMStateItem();
                item.Read(reader);
                this.rgStates.Add(item);
            }
        }

        private byte Abc
        {
            get { byte result = 0;
            if (this.fIconOnly)result |= 0x01;
            if (this.reserved2) result |= 0x02;
            if (this.fReverse) result |= 0x04;
                return result;
            }
        }

        public override void Write(BinaryWriter writer)
        {
            writer.Write(unused);
            writer.Write(this.reserved1);
            byte cStates = (byte) this.rgStates.Count;
            writer.Write(cStates);
            writer.Write((byte)this.iIconSet);
            writer.Write(this.Abc);
            foreach (var state in this.rgStates)
                state.Write(writer);
        }
    }
}